import { Decimal } from 'decimal.js';

const core = require('mathjs/core');

const math = core.create();

math.import(require('mathjs/lib/function/arithmetic/add'));
math.import(require('mathjs/lib/function/arithmetic/subtract'));
math.import(require('mathjs/lib/function/arithmetic/multiply'));
math.import(require('mathjs/lib/function/arithmetic/divide'));
math.import(require('mathjs/lib/function/arithmetic/floor'));
math.import(require('mathjs/lib/function/probability/combinations'));


_.mixin({
  // 首字母大写
  ucFirst(string) {
    return string.replace(/\b\w+\b/g, word => word.substring(0, 1)
      .toUpperCase() + word.substring(1));
  },

  combinations: math.combinations,

  serializeObject(serializeArray) {
    return _.reduce(serializeArray, (obj, prop) => {
      if (prop.name.indexOf('[]') === -1) {
        obj[prop.name] = prop.value;
      } else {
        prop.name = prop.name.replace('[]', '');
        if (_.isArray(obj[prop.name])) {
          obj[prop.name].push(prop.value);
        } else {
          obj[prop.name] = [prop.value];
        }
      }

      return obj;
    }, {});
  },

  unique(arr) {
    const unique = [];
    const repeat = [];
    const hash = {};

    if (!_.isEmpty(arr)) {
      const { length } = arr;
      let i = 0;
      let
        elem;
      for (; i < length; i++) {
        elem = arr[i];
        if (!hash[elem]) {
          unique.push(elem);
          hash[elem] = true;
        } else {
          repeat.push(elem);
        }
      }
    }

    return {
      unique,
      repeat,
    };
  },

  zhLength(str) {
    return str.replace(/[\u4e00-\u9fa5]/g, '**').length;
  },

  fixedConvert2yuan(money, options) {
    options = _.extend({}, {
      fixed: 3,
      clear: false,
    }, options);
    return _.convert2yuan(money, options);
  },

  convert2yuan(money, options) {
    options = _.extend({}, {
      fixed: 4,
      ratio: 10000,
      clear: true,
    }, options);

    return _.formatDiv(money, options.ratio, options);
  },

  convert2Rate(money, options) {
    options = _.extend({}, {
      fixed: 2,
      ratio: 100,
      clear: true,
    }, options);

    return _.formatDiv(money, options.ratio, options);
  },

  formatDiv(money, ratio, options) {
    let format;

    money = money || 0;

    options = _.extend({}, {}, options);

    if (!_.isUndefined(money)) {
      format = _.div(money, ratio);

      if (options.fixed || options.fixed === 0) {
        format = format.toFixed(options.fixed);
      }

      if (options.clear) {
        format = math.add(format, 0);
      }
    }

    return format;
  },

  formatMul(money, ratio, { clear = true, fixed = 0 } = {
    clear: true,
    fixed: 4,
  }) {
    let format;

    if (!_.isUndefined(money)) {
      format = _.mul(money, ratio);

      if (fixed) {
        format = format.toFixed(fixed);
      }

      if (clear) {
        format = math.add(format, 0);
      }
    }

    return format;
  },

  toLink(arg) {
    const { href } = window.location;
    const index = href.indexOf('/index.html');
    if (index > -1) {
      return href.substring(0, index) + arg;
    }
    return href.substring(0, href.indexOf('/#')) + arg;
  },
  sex(value) {
    return value == 1 ? '男' : '女';
  },
  // 格式化时间
  toTime(timestamp, format) {
    if (!timestamp) {
      return '--';
    }
    return timestamp ? moment(timestamp)
      .format(format || 'YYYY-MM-DD H:mm:ss') : timestamp;
  },
  // 手机版本更新项目类型
  // {title: '现金网-APP', value: 0},
  // {title: '代理-APP', value: 2},
  // {title: '体育-APP', value: 1},
  appType(value) {
    switch (value) {
      case 0:
        return '现金网-APP';
      case 1:
        return '体育-APP';
      case 2:
        return '代理-APP';
      default:
        return '--';
    }
  },
  // 手机版本更新手机端类型
  //  {title: '全部', value: -1},
  //   {title: 'IOS', value: 3},
  //   {title: '安卓', value: 2},
  clientType(value) {
    switch (value) {
      case 3:
        return 'IOS';
      case 2:
        return '安卓';
      default:
        return '--';
    }
  },
  toDate(timestamp, format) {
    timestamp = parseInt(timestamp, 10);
    return timestamp ? moment(timestamp)
      .format(format || 'YYYY-MM-DD') : timestamp;
  },

  toMonth(timestamp, format) {
    return timestamp ? moment(timestamp)
      .format(format || 'YYYY.MM') : timestamp;
  },

  // 格式化时间
  formatTime(timestamp, format) {
    return timestamp ? moment(timestamp)
      .format(format || 'YYYY-MM-DD H:mm:ss') : timestamp;
  },

  formatDate(timestamp, format) {
    return timestamp ? moment(timestamp)
      .format(format || 'YYYY-MM-DD') : timestamp;
  },

  formatAMPM(timestamp, format) {
    return timestamp ? moment(timestamp)
      .format(format || 'h:mm A') : timestamp;
  },

  getNameByObj(arr, obj) {
    return _.find(arr, obj).name;
  },

  add(arg1, arg2) {
    return math.add(arg1, arg2);
  },

  // 除法   arg1除arg2
  div(arg1, arg2) {
    arg1 = arg1 || 0;
    return math.divide(arg1, arg2);
  },

  // 乘法  arg1乘arg2
  mul(arg1, arg2) {
    arg1 = arg1 || 0;
    return math.multiply(arg1, arg2);
  },

  // 减法 arg1减arg2
  sub(arg1, arg2) {
    const n1 = new Decimal(arg1);
    const n2 = new Decimal(arg2);
    return n1.minus(n2);
  },
  /**
   ** 减法函数，用来得到精确的减法结果
   ** 说明：javascript的减法结果会有误差，在两个浮点数相减的时候会比较明显。这个函数返回较为精确的减法结果。
   ** 调用：accSub(arg1,arg2)
   ** 返回值：arg1加上arg2的精确结果
   * */
  accSub(arg1, arg2) {
    let r1;
    let r2;
    let m;
    let
      n;
    try {
      r1 = arg1.toString()
        .split('.')[1].length;
    } catch (e) {
      r1 = 0;
    }
    try {
      r2 = arg2.toString()
        .split('.')[1].length;
    } catch (e) {
      r2 = 0;
    }
    m = Math.pow(10, Math.max(r1, r2)); // last modify by deeka //动态控制精度长度
    n = (r1 >= r2) ? r1 : r2;
    return ((arg1 * m - arg2 * m) / m).toFixed(n);
  },
  ceilDecimal(decimal, precision) {
    decimal = decimal.toFixed(precision + 1);
    return decimal.substring(0, decimal.lastIndexOf('.') + precision + 1); // 123456.78
  },

  floor(arg1, index) {
    const sArg1 = String(arg1);
    const pos = sArg1.indexOf('.');
    if (pos > -1) {
      return Number(sArg1.substring(0, pos + index + 1));
    }
    return arg1;
  },

  /**
   *
   * https://github.com/freearhey/vue2-filters.git
   * 12345 => $12,345.00
   *
   * @param {String} symbol
   * @param {Number} decimals Decimal places
   * @param {Object} options
   */

  currency(value, symbol = '', decimals = 2, options) {
    let thousandsSeparator;
    let symbolOnLeft;
    let
      spaceBetweenAmountAndSymbol;
    const digitsRE = /(\d{3})(?=\d)/g;
    options = options || {};
    value = parseFloat(value);
    if (!isFinite(value) || (!value && value !== 0)) return '';
    // symbol = symbol != null ? symbol : '';
    // decimals = decimals != null ? decimals : 2;
    thousandsSeparator = options.thousandsSeparator != null ? options.thousandsSeparator : ',';
    symbolOnLeft = options.symbolOnLeft != null ? options.symbolOnLeft : true;
    spaceBetweenAmountAndSymbol = options.spaceBetweenAmountAndSymbol != null ? options.spaceBetweenAmountAndSymbol : false;
    // let stringified = Math.abs(value).toFixed(decimals);
    let stringified = _.floor(Math.abs(value), decimals)
      .toFixed(decimals);
    if (options.type && options.type === 1) { // type 等于1表示进行四舍五入 2表示无条件进位  默认情况为无条件舍弃
      stringified = _.round(Math.abs(value), decimals)
        .toFixed(decimals);
    } else if (options.type && options.type === 2) {
      stringified = _.ceil(Math.abs(value), decimals)
        .toFixed(decimals);
    }

    stringified = options.decimalSeparator
      ? stringified.replace('.', options.decimalSeparator)
      : stringified;
    const _int = decimals
      ? stringified.slice(0, -1 - decimals)
      : stringified;
    const i = _int.length % 3;
    const head = i > 0
      ? (_int.slice(0, i) + (_int.length > 3 ? thousandsSeparator : ''))
      : '';
    const _float = decimals
      ? stringified.slice(-1 - decimals)
      : '';
    symbol = spaceBetweenAmountAndSymbol
      ? (symbolOnLeft ? `${symbol} ` : ` ${symbol}`)
      : symbol;
    symbol = symbolOnLeft
      ? symbol + head
      + _int.slice(i)
        .replace(digitsRE, `$1${thousandsSeparator}`) + _float
      : head
      + _int.slice(i)
        .replace(digitsRE, `$1${thousandsSeparator}`) + _float + symbol;
    const sign = value < 0 ? '-' : '';
    return sign + symbol;
  },

  /**
   * 键盘验证
   */
  validateNumber(keyCode) {
    // 数字
    if (keyCode >= 48 && keyCode <= 57) return true;
    // 小数字键盘
    if (keyCode >= 96 && keyCode <= 105) return true;
    // Backspace, del, 左右方向键
    return keyCode === 8 || keyCode === 46 || keyCode === 37 || keyCode === 39;
  },

  bankNumber(cardno) {
    return cardno.toString()
      .replace(/(\d{4})(?=\d)/g, '$1 ');
  },

  // 细分类型
  toConverter(value, constName, opts) {
    if (_.isArray(value)) {
      return _.map(value, _.partial(_._toConverter, _, constName));
    }
    return _._toConverter(parseInt(value), constName, opts);
  },

  _toConverter(value, constName, opts) {
    try {
      /*
      *  审核状态单独处理
      *  初审通过 1
         终审通过 3
         未审核 0
         已拒绝 2 4
      * */
      if (constName === 'COMMISSION_AUDIT_STATUS') {
        if (opts.type == 1) {
          // 初审状态
          switch (Number(value)) {
            case 0:
              return '未审核';
            case 1:
            case 3:
            case 4:
              return '通过';
            case 2:
              return '拒绝';
            default:
              break;
          }
        } else {
          // 终审状态
          switch (Number(value)) {
            case 0:
            case 1:
            case 2:
              return '未审核';
            case 3:
              return '通过';
            case 4:
              return '拒绝';
            default:
              break;
          }
        }
      }
      if (constName === 'GAME_ID') {
        return _.find(consts[constName], { gamePlatformId: value }).title;
      }
      return _.isArray(constName) ? (_.find(constName, { value }).title || _.find(constName, { value }).label)
        : (_.find(consts[constName], { value }).title || _.find(consts[constName], { value }).label);
    } catch (e) {
      // throw new Error(`${constName}没有找到对应的值${value}`);
      return '--';
    }
  },

  revertConverter(title, constName) {
    if (_.isArray(value)) {
      return _.map(value, _.partial(_._revertConverter, _, constName));
    }
    return _._revertConverter(value, constName);
  },

  _revertConverter(title, constName) {
    return _.find(consts[constName], { title }).value;
  },

  toPeriod({
    // start: [0, 'week'],
    // end: [0, 'week'],
    start = [],
    end = [],
    format = 'YYYY-MM-DD H:mm:ss',
  }) {
    return {
      startTime: moment()
        .add(start[0], start[1])
        .startOf(start[1])
        .format(format),
      endTime: moment()
        .add(end[0], end[1])
        .endOf(end[1])
        .format(format),
    };
  },


  /**
   * 获取操作内容-路由标题链
   * @param route 当前路由
   * @param ignore 是否忽略不记录操作日志的标示
   * @returns {*}
   */
  getContent(route, title = '', ignore) {
    if (route) {
      if (route.meta && (ignore || !route.meta.notLog)) {
        if (route.matched && route.matched.length > 0) {
          const self = route.matched[route.matched.length - 1];
          // let parent = self.parent;
          title = this._getTitle(self, title);
        }
      }
    }
    return title;
  },

  /**
   * 获取路由标题
   * @param route 当前路由
   * @param title 子标题
   * @returns {*}
   * @private
   */
  _getTitle(route, title) {
    if (route) {
      if (route.meta) {
        const currentTitle = route.meta.title;
        if (title) {
          title = `${currentTitle}-${title}`;
        } else {
          title = currentTitle;
        }
      }
      title = _._getTitle(route.parent, title);
    }
    return title;
  },
  // 用于生成uuid
  _S4() {
    return (((1 + Math.random()) * 0x10000) | 0).toString(16)
      .substring(1);
  },
  guid() {
    return (`${this._S4() + this._S4()}-${this._S4()}-${this._S4()}-${this._S4()}-${this._S4()}${this._S4()}${this._S4()}`);
  },
  formatUserPhoneEmail(val, partial, all) { // 当前账户是否有手机号邮箱的查看权限
    let res = '';
    if (val && val != '') {
      if (partial) {
        if (val.indexOf('**') > -1) {
          res = val;
        } else if (val.indexOf('@') > -1) {
          const emailArr = val.split('@');
          res = `${emailArr[0].slice(0, 3)}***@${emailArr[1]}`;
        } else {
          const valArray = val.split(' ');
          // 含区号的时候长度大于1
          if (valArray.length > 1) {
            res = `${valArray[0]} ${valArray[1].slice(0, 3)}****${valArray[1].slice(valArray[1].length - 4, valArray[1].length)}`;
          } else {
            res = `${val.slice(0, 3)}****${val.slice(val.length - 4, val.length)}`;
          }
        }
      }
      if (all) {
        res = val;
      }
    }
    return res;
  },
});

Vue.filter('formatDiv', _.formatDiv);
Vue.filter('formatMul', _.formatMul);
Vue.filter('toDate', _.toDate);
Vue.filter('toMonth', _.toMonth);
Vue.filter('toTime', _.toTime);
Vue.filter('fixedConvert2yuan', _.fixedConvert2yuan);
Vue.filter('convert2yuan', _.convert2yuan);
Vue.filter('convert2Rate', _.convert2Rate);
Vue.filter('bankNumber', _.bankNumber);
Vue.filter('toConverter', _.toConverter);
Vue.filter('revertConverter', _.revertConverter);
Vue.filter('join', _.join);
Vue.filter('sex', _.sex);
Vue.filter('appType', _.appType);
Vue.filter('clientType', _.clientType);
Vue.filter('getNameByObj', _.getNameByObj);
Vue.filter('formatDate', _.formatDate);
Vue.filter('formatTime', _.formatTime);
Vue.filter('currency', _.currency);
